<!--
入参：
boxType：组件类型（不传则默认曲线，"line"）
         柱状图："bar"
         柱状堆叠："barStack"，
         Y轴目录，X轴数值："barYLine"
         Y轴目录，X轴数值堆叠："barYLineStack"，
         双Y轴曲线："doubleYLine"
         双Y轴柱状图："doubleYBar"
         折线图："lineSmooth"
         rotate:x轴倾斜角度，默认0
interval:x轴合并个数，从0开始，默认‘auto’
legendData：图例数据 类型：[]
xData：目录数据      类型：[]
yData：展示数据数值  类型：[[],[]]
xName: x轴标题
yName：左侧数值标题      类型：""
yName1：右侧数值标题      类型：""
markPoint：预警点     不为""则展示最大和最小，不传或""则不显示
markLine：预警线    不传或""则不显示 传入则显示示例如下
          markLine：{markData:50,label:"预警值：50kW"}
seriesName：饼图，圆环图legendData=[] 时 启用seriesName 类型:[]
toolName：提示框名称（标题）与xData保持数量一致 不传提示框标题为xData
max：曲线、柱状图的最大值，不传自动计算，传入则显示y轴最大值为此值。
示例1：
boxType="line"
     legendData= ['邮件营销','联盟广告','视频广告','直接访问','搜索引擎']
     xData=['周一','周二','周三','周四','周五','周六','周日']
     yName="(Thd%)";
     title='折线图堆叠'
     yData=[[120, 132, 101, 134, 90, 230, 210],[220, 182, 191, 234, 290, 330, 310],[320, 332, 301, 334, 390, 330, 320]
            [150, 232, 201, 154, 190, 330, 410],[170, 222, 201, 154, 190, 230, 310],[190, 212, 201, 154, 290, 230, 410]
          ,[100, 212, 101, 154, 120, 130, 210]]
-->
<template>
  <div class="echarts">
    <div ref="echartsBox" class="echartsBox" />
  </div>
</template>
<script>
import * as echarts from 'echarts';
export default {
  name: 'echartBox',
  props: {
    'legendConfig': {
      type: [Object], default: function() {
        // orient:"horizontal"/"vertical"
        // align:"auto"/"left"/"right"
        // left:"left"/"center"/"right"/px值/百分比值
        // top:'top'/ 'middle'/ 'bottom'/px值/百分比值
        // auto:均可替换成一定的px值/百分比值
        return {
          left: 'center',
          right: 'auto',
          top: 'bottom',
          bottom: '30rem',
          orient: 'horizontal',
          width: 'auto',
          height: 'auto',
          align: 'auto'
        };
      }
    },
    'grid': {
      type: [Object], default: function() {
        return {
          top: '30px', left: '4%', right: '4%', bottom: '30px', containLabel: true
        };
      }
    },
    'interval': {
      type: [Number, String], default: function() {
        return 'auto';
      }
    },
    'rotate': {
      type: Number, default: function() {
        return 0;
      }
    },
    'legendData': {
      type: Array, default: function() {
        return [];
      }
    },
    'xData': {
      type: Array, default: function() {
        return [];
      }
    },
    'yData': {
      type: Array, default: function() {
        return [];
      }
    },
    'title': {
      type: String, default: function() {
        return '';
      }
    },
    'yName': {
      type: String, default: function() {
        return '';
      }
    },
    'xName': {
      type: String, default: function() {
        return '';
      }
    },
    'boxType': {
      type: String, default: function() {
        return 'line';
      }
    },
    'markPoint': {
      type: [Object, String], default: function() {
        return '';
      }
    },
    'markLine': {
      type: [Object, String], default: function() {
        return '';
      }
    },
    'markArea': { type: [Object, String], default: () => '' },
    'yName1': {
      type: String, default: function() {
        return '';
      }
    },
    'seriesName': {
      type: [Array, String], default: function() {
        return '';
      }
    },
    'toolName': {
      type: [Array, String], default: function() {
        return '';
      }
    },
    'max': {
      type: [Number, String], default: function() {
        return undefined;
      }
    },
    'color': {
      type: [Array, String], default: function() {
        return '';
      }
    }
  },
  data() {
    return {
      series: []
    };
  },
  computed: {
    rtColor: function() {
      if (this.color) {
        return this.color;
      } else {
        return [
          '#2F8EE0',
          '#6FD088',
          '#F85778',
          '#FFBC47',
          '#287dc6',
          '#52aa69',
          '#d64c68',
          '#e19d26',
          '#34a1ff',
          '#81f29e',
          '#ff819b',
          '#fea407'
        ];
      }
    },
    // echars数据处理
    option() {
      // 折线，柱状图公用Option
      const lienOption = this.getLineOption();
      let markLine = null;
      if (this.markLine) {
        markLine = this.getMarkLine();
      }
      const markPoint = this.getMarkPoint();
      // 曲线图
      if (this.boxType === null || this.boxType === 'line') {
        return this.getLine(lienOption, markPoint, markLine);
      } else if (this.boxType === 'lineSmooth') {
        return this.getLineSmooth(lienOption);
      } else if (this.boxType === 'bar') {
        return this.getBar(lienOption, markPoint, markLine);
      } else if (this.boxType === 'barStack') {
        return this.getBarStack(lienOption);
      } else if (this.boxType === 'barYLine') {
        return this.getBarYLine(lienOption);
      } else if (this.boxType === 'barYLineStack') {
        return this.getBarYLineStack(lienOption);
      } else if (this.boxType === 'doubleYLine') {
        return this.getDoubleYLine(lienOption);
      } else if (this.boxType === 'doubleYBar') {
        return this.getDoubleYBar(lienOption);
      } else {
        return lienOption;
      }
    }
  },
  watch: {
    option: {
      handler() {
        echarts.init(this.$refs.echartsBox).resize();
        echarts.init(this.$refs.echartsBox).setOption(this.option, true);
      }
    }
  },
  mounted() {
    const thir = this;
    window.onresize = function() {
      thir.watchChangeSize();
    };
    echarts.init(this.$refs.echartsBox).setOption(this.option, true);
    echarts.init(this.$refs.echartsBox).resize();
  },
  methods: {
    watchChangeSize() {
      echarts.init(this.$refs.echartsBox).resize();
    },
    init() {
      echarts.init(this.$refs.echartsBox).setOption(this.option, true);
    },
    setSeries(obj) {
      this.series.push(obj);
    },
    resetSeries() {
      this.series = [];
    },
    getLineOption() {
      const targer = this;
      return {
        animation: false,
        color: targer.rtColor,
        title: {
          textStyle: { color: '#fff', fontSize: '14px', fontFamily: 'Arial, SimHei' },
          text: this.title,
          left: 'center'
        },
        // dataZoom: [{ show: true, type: 'inside', realtime: true, start: 0, end: 100 }],
        tooltip: {
          transitionDuration: 0,
          position: 'inside',
          fontFamily: 'Arial, SimHei',
          trigger: 'axis',
          extraCssText: 'z-index:99999',
          formatter: function(params) {
            let bt = '';
            let index = 0;
            for (let i = 0; i < params.length; i++) {
              if (targer.toolName) {
                // 有toolName
                index = params[i].dataIndex;
                let sri = '';
                if (targer.legendData.length > 0) {
                  sri = params[i].seriesName + ':';
                } else if (targer.seriesName && targer.seriesName.length > 0) {
                  sri = targer.seriesName[i] + ':';
                }
                if (i > 0 && targer.yName1) {
                  bt += sri + params[i].value + targer.yName1 + '<br/>';
                } else {
                  bt += sri + params[i].value + targer.yName + '<br/>';
                }
              } else {
                // 无toolName
                let sri = '';
                if (targer.legendData.length > 0) {
                  sri = params[i].seriesName + ':';
                } else if (
                    targer.seriesName !== undefined &&
                    targer.seriesName.length > 0
                ) {
                  sri = targer.seriesName[0] + ':';
                }
                if (i > 0 && targer.yName1) {
                  bt += sri + params[i].value + targer.yName1 + '<br/>';
                } else {
                  bt += sri + params[i].value + targer.yName + '<br/>';
                }
              }
            }
            if (targer.toolName) {
              bt = targer.toolName[index] + '<br>' + bt;
            } else {
              bt = params[0].name + '<br>' + bt;
            }
            return bt; // targer.yName;
          }
        },
        legend: {
          textStyle: {
            color: '#b8b8b8',
            fontFamily: 'Arial, SimHei'
          },
          data: this.legendData,
          ...this.legendConfig
          // bottom: 0
        },
        grid: {
          ...this.grid
        },
        xAxis: {
          axisLine: {
            lineStyle: {
              type: 'solid',
              color: '#b8b8b8', // 左边线的颜色
              width: '1' // 坐标线的宽度
            }
          },
          axisLabel: {
            interval: this.interval !== undefined && this.interval !== '' ? this.interval : 'auto',
            show: false,
            rotate: this.rotate ? this.rotate : 0,
            textStyle: {
              color: '#b8b8b8',
              fontFamily: 'Arial, SimHei'
            },
          },
          type: 'category',
          boundaryGap: false,
          name: this.xName,
          nameTextStyle: {
            padding: [0, 0, 10, 0],
            color: '#b8b8b8',
            fontFamily: 'Arial, SimHei'
          },
          data: this.xData
        },
        yAxis: {
          max: targer.max,
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(228,228,228,0.2)',
              width: 1
            }
          },
          axisLine: {
            show: false,
            lineStyle: {
              type: 'solid',
              color: '#b8b8b8', // 左边线的颜色
              width: '1' // 坐标线的宽度
            }
          },
          axisTick: {
            show: false,
          },
          axisLabel: {
            // formatter: '{value}',
            show: true,
            textStyle: {
              color: '#666',
              fontFamily: 'Arial, SimHei'
            },
            formatter: function(params){
              var newParamsName = "";// 最终拼接成的字符串
              var paramsNameNumber = params.length;// 实际标签的个数
              var provideNumber = 7;// 每行能显示的字的个数
              var rowNumber = Math.ceil(paramsNameNumber / provideNumber);// 计算行数，向上取整
          　　//判断是否需要换行
              if (paramsNameNumber > provideNumber) {
                //循环得到每行的显示内容，p代表行
                for (var p = 0; p < rowNumber; p++) {
                  var tempStr = "";// 表示每一次截取的字符串
                  var start = p * provideNumber;// 开始截取的位置
                  var end = start + provideNumber;// 结束截取的位置
                  if (p == rowNumber - 1) {
                  // 最后一次不换行
                    tempStr = params.substring(start, paramsNameNumber);
                  } else {
      　　　　　　　　// 每一次拼接字符串并换行
                    tempStr = params.substring(start, end) + "\n";
                  }
                  newParamsName += tempStr;// 最终拼成的字符串
                }
              } else {
                // 将旧标签的值赋给新标签
                newParamsName = params;
              }
              return newParamsName
            }
          },
          minInterval:1,
          data: [],
          type: 'value',
          name: this.yName,
          nameTextStyle: {
            padding: [0, 0, 0, 10],
            color: '#b8b8b8'
          }
        },
        series: []
      };
    },
    getMarkLine() {
      return {
        symbol: 'none',
        silent: true,
        label: {
          position: 'middle', // 将警示值放在哪个位置，三个值“start”,“middle”,“end” 开始 中点 结束
          formatter: this.markLine.label,
          color: 'rgb(255,215,0)',
          fontSize: 14,
          fontFamily: 'Arial, SimHei'
        },
        data: [
          {
            yAxis: this.markLine.markData,
            itemStyle: {
              normal: {
                show: true,
                color: 'rgb(255,215,0)',
                fontFamily: 'Arial, SimHei',
                lineStyle: {
                  // 警戒线的样式 ，虚实 颜色
                  type: 'dashed',
                  width: 3,
                  color: 'rgb(255,215,0)'
                }
              }
            }
          }
        ]
      };
    },
    getMarkPoint() {
      return {
        data: [
          { type: 'max', name: '最大值' },
          { type: 'min', name: '最小值' }
        ]
      };
    },
    getLine(lienOption, markPoint, markLine) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        if (this.markPoint) {
          // 有预警点
          if (markLine != null) {
            // 有预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'line',
              smooth: true,
              data: this.yData[i],
              markLine: markLine,
              markPoint: markPoint,
              connectNulls: true,
              markArea: this.markArea ? this.markArea : ''
              // symbol: "none"
            });
          } else {
            // 有预警点 无预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'line',
              smooth: true,
              data: this.yData[i],
              markPoint: markPoint,
              connectNulls: true,
              markArea: this.markArea ? this.markArea : ''
              // symbol: "none"
            });
          }
        } else {
          // 无预警点
          if (markLine != null) {
            // 有预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'line',
              smooth: true,
              data: this.yData[i],
              markLine: markLine,
              connectNulls: true,
              markArea: this.markArea ? this.markArea : ''
              // symbol: "none"
            });
          } else {
            // 无预警点 无预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'line',
              smooth: true,
              data: this.yData[i],
              connectNulls: true,
              markArea: this.markArea ? this.markArea : ''
              // symbol: "none"
            });
          }
        }
      }
      lienOption.xAxis.boundaryGap = false;
      lienOption.series = this.series;
      return lienOption;
    },
    getLineSmooth(lienOption) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        this.setSeries({
          name: this.legendData[i],
          type: 'line',
          smooth: false,
          data: this.yData[i],
          connectNulls: true,
          itemStyle: {
            normal: {
              label: {
                show: true,  //开启显示
                position: 'top',  //在上方显示
                color: '#333'
              }
            }
          }
        });
      }
      lienOption.xAxis.boundaryGap = false;
      lienOption.yAxis.name = this.yName;
      lienOption.yAxis.name = this.yName1;
      lienOption.series = this.series;
      return lienOption;
    },
    getBar(lienOption, markPoint, markLine) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        if (this.markPoint) {
          // 有预警点
          if (markLine != null) {
            // 有预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'bar',
              smooth: true,
              data: this.yData[i],
              barWidth: '30%',
              barGap: '0px',
              markLine: markLine,
              markPoint: markPoint,
              itemStyle: {
                normal: {
                  label: {
                    show: true,  //开启显示
                    position: 'right',  //在上方显示
                    color: '#333'
                  }
                }
              }
            });
          } else {
            // 有预警点 无预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'bar',
              smooth: true,
              barWidth: '30%',
              barGap: '0px',
              data: this.yData[i],
              markPoint: markPoint,
              itemStyle: {
                normal: {
                  label: {
                    show: true,  //开启显示
                    position: 'right',  //在上方显示
                    color: '#333'
                  }
                }
              }
            });
          }
        } else {
          // 无预警点
          if (markLine != null) {
            // 有预警线
            this.setSeries({
              barGap: '0px',
              barWidth: '30%',
              name: this.legendData[i],
              type: 'bar',
              smooth: true,
              data: this.yData[i],
              markLine: markLine,
              itemStyle: {
                normal: {
                  label: {
                    show: true,  //开启显示
                    position: 'right',  //在上方显示
                    color: '#333'
                  }
                }
              }
            });
          } else {
            // 无预警点 无预警线
            this.setSeries({
              name: this.legendData[i],
              type: 'bar',
              smooth: true,
              barWidth: '26%',
              barGap: '0.1px',
              data: this.yData[i],
              itemStyle: {
                normal: {
                  label: {
                    show: true,  //开启显示
                    position: 'right',  //在上方显示
                    color: '#333'
                  }
                }
              }
            });
          }
        }
      }
      lienOption.xAxis.boundaryGap = true;
      lienOption.series = this.series;
      return lienOption;
    },
    getBarStack(lienOption) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        this.setSeries({
          name: this.legendData[i],
          barWidth: '30%',
          type: 'bar',
          stack: '总量',
          smooth: true,
          data: this.yData[i]
        });
      }
      lienOption.xAxis.boundaryGap = true;
      lienOption.series = this.series;
      return lienOption;
    },
    getBarYLine(lienOption) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        this.setSeries({
          name: this.legendData[i],
          type: 'bar',
          smooth: true,
          data: this.yData[i],
          barWidth: '26%',
          itemStyle: {
            normal: {
              label: {
                show: true,  //开启显示
                position: 'right',  //在上方显示
                color: '#333'
              }
            }
          }
        });
      }
      lienOption.xAxis.boundaryGap = true;
      lienOption.xAxis.type = 'value';
      lienOption.xAxis.name = this.yName;
      lienOption.xAxis.splitLine = {
        show: true,
        lineStyle: {
          color: 'rgba(228,228,228,0.2)',
          width: 1
        }
      };
      lienOption.yAxis.type = 'category';
      lienOption.yAxis.name = '';
      lienOption.yAxis.splitLine.show = false;
      lienOption.yAxis.data = this.xData;
      lienOption.grid.right = this.grid.right ? this.grid.right : '15%';
      lienOption.series = this.series;
      return lienOption;
    },
    getBarYLineStack(lienOption) {
      this.resetSeries();
      for (let i = 0; i < this.yData.length; i++) {
        this.setSeries({
          name: this.legendData[i],
          type: 'bar',
          stack: '总量',
          smooth: true,
          barWidth: '30%',
          data: this.yData[i]
        });
      }
      lienOption.xAxis.boundaryGap = true;
      lienOption.xAxis.type = 'value';
      lienOption.xAxis.name = this.yName;
      lienOption.xAxis.splitLine = {
        show: true,
        lineStyle: {
          color: 'rgba(228,228,228,0.2)',
          width: 1
        }
      };
      lienOption.yAxis.type = 'category';
      lienOption.yAxis.name = '';
      lienOption.yAxis.splitLine.show = false;
      lienOption.yAxis.data = this.xData;
      lienOption.grid.right = this.grid.right ? this.grid.right : '30%';
      lienOption.series = this.series;
      return lienOption;
    },
    getDoubleYLine(lienOption) {
      lienOption.yAxis = [
        {
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(228,228,228,0.2)',
              width: 1
            }
          },
          axisLine: {
            lineStyle: {
              type: 'solid',
              color: 'rgba(255,255,255,0.8)', // 左边线的颜色
              width: '2' // 坐标线的宽度
            }
          },
          axisLabel: {
            formatter: '{value}',
            show: true,
            textStyle: {
              color: '#fff'
            }
          },
          data: [],
          type: 'value',
          name: this.yName,
          nameTextStyle: {
            padding: [0, 0, 0, 10],
            color: '#fff'
          }
        },
        {
          splitLine: {
            show: false,
            lineStyle: {
              color: 'rgba(228,228,228,0.2)',
              width: 1
            }
          },
          axisLine: {
            lineStyle: {
              type: 'solid',
              color: 'rgba(255,255,255,0.8)', // 左边线的颜色
              width: '2' // 坐标线的宽度
            }
          },
          axisLabel: {
            formatter: '{value}',
            show: true,
            textStyle: {
              color: '#fff'
            }
          },
          data: [],
          type: 'value',
          name: this.yName1,
          nameTextStyle: {
            padding: [0, 10, 0, 0],
            color: '#fff'
          }
        }
      ];
      this.resetSeries();
      this.setSeries({
        name: this.legendData[0],
        type: 'line',
        smooth: true,
        yAxisIndex: 0,
        data: this.yData[0],
        connectNulls: true
      });
      this.setSeries({
        name: this.legendData[1],
        type: 'line',
        smooth: true,
        yAxisIndex: 1,
        data: this.yData[1],
        connectNulls: true
      });
      lienOption.series = this.series;
      return lienOption;
    },
    getDoubleYBar(lienOption) {
      lienOption.yAxis = [
        {
          splitLine: {
            show: true,
            lineStyle: {
              color: 'rgba(228,228,228,0.2)',
              width: 1
            }
          },
          axisLine: {
            lineStyle: {
              type: 'solid',
              color: '#b8b8b8', // 左边线的颜色
              width: '1' // 坐标线的宽度
            }
          },
          axisLabel: {
            formatter: '{value}',
            show: true,
            textStyle: {
              color: '#b8b8b8'
            }
          },
          data: [],
          type: 'value',
          name: this.yName,
          nameTextStyle: {
            padding: [0, 0, 0, 10],
            color: '#b8b8b8'
          }
        },
        {
          splitLine: {
            show: false,
            lineStyle: {
              color: 'rgba(228,228,228,0.2)',
              width: 1
            }
          },
          axisLine: {
            lineStyle: {
              type: 'solid',
              color: '#b8b8b8', // 左边线的颜色
              width: '1' // 坐标线的宽度
            }
          },
          axisLabel: {
            formatter: '{value}',
            show: true,
            textStyle: {
              color: '#b8b8b8'
            }
          },
          data: [],
          type: 'value',
          name: this.yName1,
          nameTextStyle: {
            padding: [0, 10, 0, 0],
            color: '#b8b8b8'
          }
        }
      ];
      this.resetSeries();
      this.setSeries({
        name: this.legendData[0],
        type: 'bar',
        smooth: true,
        barWidth: '20%',
        yAxisIndex: 0,
        data: this.yData[0],
        itemStyle: {
          normal: {
            label: {
              show: true,  //开启显示
              position: 'top',  //在上方显示
              color: '#333'
            }
          }
        }
      });
      this.setSeries({
        name: this.legendData[1],
        type: 'bar',
        smooth: true,
        barWidth: '20%',
        yAxisIndex: 1,
        data: this.yData[1],
        itemStyle: {
          normal: {
            label: {
              show: true,  //开启显示
              position: 'top',  //在上方显示
              color: '#333'
            }
          }
        }
      });
      lienOption.xAxis.boundaryGap = true;
      lienOption.series = this.series;
      return lienOption;
    }
  }
};
</script>
<style scoped>
.echarts {
  width: 100%;
  height: 100%;
}

.echartsBox {
  width: 100%;
  height: 100%;
}
</style>
